package cn.zwx.common.resilience4j.filter;


import cn.zwx.base.entity.ResponseEntity;
import cn.zwx.base.enums.ResponseCodeEnum;
import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;

/**
 * @author zhangwenxue
 */
@Activate(group = {CONSUMER,PROVIDER},order = Integer.MAX_VALUE-1)
public class Resilience4jCircuitBreakerFilter implements Filter {

    public static final Logger logger = LoggerFactory.getLogger(Resilience4jCircuitBreakerFilter.class);

    public static final String CALL_NOT_PERMITTED_EXCEPTION_CLASS_NAME = "io.github.resilience4j.circuitbreaker.CallNotPermittedException";
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result result = invoker.invoke(invocation);
        if (result.hasException() && invoker.getInterface() != GenericService.class) {
            Throwable exception = result.getException();
             if (CALL_NOT_PERMITTED_EXCEPTION_CLASS_NAME.equals(exception.getClass().getName())){
                 logger.error("invoker:interfaceClass:{}#{},请求参数：{}",invoker.getInterface(),invocation.getMethodName(),
                         JSON.toJSONString(invocation.getArguments()),exception);
                 result.setException(null);
                 ResponseCodeEnum responseCodeEnum =  ResponseCodeEnum.CALL_NOT_PERMITTED_ERROR;
                 result.setValue(ResponseEntity.fail(responseCodeEnum.getCode(),responseCodeEnum.getMsg()));
             }
            return result;
        }
        return result;
    }
}
